package com.wy.w_ui.refresh;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
import android.widget.Scroller;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;


import com.wy.w_ui.refresh.utils.WScrollUtil;

/**
 * 刷新控件容器
 */
public class WRefreshLayout extends FrameLayout implements IWRefresh {

    private WOverView.WRefreshState refreshState;
    private GestureDetector gestureDetector;
    private IWRefresh.IWRefreshListener refreshListener;
    protected WOverView overView;
    private int lastY;
    //刷新时是否禁止滚动
    private boolean disableRefreshScroll;
    private AutoScroller autoScroller;

    public WRefreshLayout(@NonNull Context context) {
        super(context);
        init();
    }

    public WRefreshLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public WRefreshLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * 实现系统的手势监听器
     */
    private WGestureListener gestureListener = new WGestureListener() {

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

            if (refreshListener != null || Math.abs(distanceX) > Math.abs(distanceY) && !refreshListener.enableRefresh()) {
                //发生了横向滑动,或者刷新被禁止
                return false;
            }

            if (disableRefreshScroll && refreshState == WOverView.WRefreshState.STATE_REFRESH) {
                //刷新时禁止滑动
                return true;
            }

            View header = getChildAt(0);
            View child = WScrollUtil.findScrollableChild(WRefreshLayout.this);
            if (WScrollUtil.childScrolled(child)) {
                //如果列表发生了滚动则不处理
                return false;
            }

            //没有刷新或没有达到可以刷新的距离.且头部已经划出或下拉
            if ((refreshState != WOverView.WRefreshState.STATE_REFRESH || header.getBottom() <= overView.mPullRefreshHeight) && (header.getBottom() > 0 || distanceY <= 0.0f)) {

                //如果还在滑动中,就是没松手
                if (refreshState != WOverView.WRefreshState.STATE_OVER_RELEASE){
                    //计算速度
                    int speed;
                    if (child.getTop() < overView.mPullRefreshHeight){
                        speed = (int) (lastY / overView.minDamp);
                    }else {
                        speed = (int) (lastY / overView.maxDamp);
                    }

                    //如果是正在刷新状态,则不允许在滑动的时候改变状态

                }

            }
            return super.onScroll(e1, e2, distanceX, distanceY);
        }
    };

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        View header = getChildAt(0);
        if (ev.getAction() == MotionEvent.ACTION_POINTER_UP
                || ev.getAction() == MotionEvent.ACTION_CANCEL
                || ev.getAction() == MotionEvent.ACTION_POINTER_INDEX_MASK) {
            //松开手的状态
            //如果头部的底部坐标大于0
            if (header.getBottom() > 0) {
                //头部被拉下来了,但是没有触发刷新
                if (refreshState != WOverView.WRefreshState.STATE_REFRESH) {
                    //非正在刷新
                    recover(header.getBottom());
                    return false;
                }
            }

            lastY = 0;

        }

        //没有松开手
        //判断事件是否被消费掉
        boolean consumed = gestureDetector.onTouchEvent(ev);
        if ((consumed || (refreshState != WOverView.WRefreshState.STATE_INIT && refreshState != WOverView.WRefreshState.STATE_REFRESH)) && header.getBottom() != 0) {

            ev.setAction(MotionEvent.ACTION_CANCEL);
            return super.dispatchTouchEvent(ev);
        }

        if (consumed) {
            return true;
        } else {
            return super.dispatchTouchEvent(ev);
        }

    }

    /**
     * 初始化方法
     */
    private void init() {

        gestureDetector = new GestureDetector(getContext(), gestureListener);
        autoScroller = new AutoScroller();
    }

    private void recover(int dis) {

        if (refreshListener != null && dis > overView.mPullRefreshHeight) {
            //滚动到指定位置:dis - overView.mPullRefreshHeight
            autoScroller.recover(dis - overView.mPullRefreshHeight);
            refreshState = WOverView.WRefreshState.STATE_OVER_RELEASE;
        } else {
            autoScroller.recover(dis);
        }
    }

    /**
     * 借助 Scroller 实现视图自动滚动
     */
    private class AutoScroller implements Runnable {

        private Scroller mScroller;
        private int mLastY;
        private boolean mIsFinished;

        public AutoScroller() {

            mScroller = new Scroller(getContext(), new LinearInterpolator());
            mIsFinished = true;
        }

        @Override
        public void run() {
            if (mScroller.computeScrollOffset()) {
                //还未滚动完成
            }

        }

        private void recover(int dis) {
            if (dis <= 0) {
                return;
            }
            removeCallbacks(this);
            mLastY = 0;
            mIsFinished = false;
            mScroller.startScroll(0, 0, 0, dis, 300);
            post(this);
        }

        boolean ismIsFinished() {
            return mIsFinished;
        }
    }

    /**
     * 根据偏移量移动header和child
     * @param offsetY 偏移量
     * @param nonAuto 是否非自动滚动触发
     * @return
     */
    private boolean moveDown(int offsetY,boolean nonAuto){

        View header = getChildAt(0);
        View child = WScrollUtil.findScrollableChild(WRefreshLayout.this);
        return true;
    }

    @Override
    public void setDisableRefreshScroll(boolean disableRefreshScroll) {
        this.disableRefreshScroll = disableRefreshScroll;
    }

    @Override
    public void refreshFinish() {

    }

    @Override
    public void setRefreshOverView(WOverView overView) {
        this.overView = overView;
    }

    @Override
    public void setRefreshListener(IWRefreshListener listener) {
        this.refreshListener = listener;
    }
}
